﻿using AutoMapper;
using Avalon.Business.ViewModels;
using Avalon.Core.Data;
using Avalon.Core.Providers;
using Avalon.Data;
using Avalon.Data.Models;
using Avalon.Repository;
using System.Linq;

namespace Avalon.Business
{
    public static class Initializer
    {
        public static void Initialize()
        {
            AvalonDbInitializer<AvalonDbContext> dbInitializer = new AvalonDbInitializer<AvalonDbContext>();
            dbInitializer.OnDatabaseCreated += (s, e) => {
                if (ProviderContainer.Current.EntityProvider != null) {
                    ProviderContainer.Current.EntityProvider.Reload();
                }
            };
            System.Data.Entity.Database.SetInitializer(dbInitializer);
            Avalon.Core.Data.RepositoryConfig.RegisterRepository(typeof(Repository<>));
            MappingInitializer();
        }

        public static void ResetContext()
        {
            ContextFactory.Reset();
        }

        private static void MappingInitializer()
        {
            Mapper.CreateMap<Character, VMCharacter>().IgnoreAllNonExisting();
            Mapper.CreateMap<Character, VMCharacter_ListItem>().IgnoreAllNonExisting();
            Mapper.CreateMap<Character, VMCharacter_DetailItem>().IgnoreAllNonExisting();
            Mapper.CreateMap<VMCharacter, Character>().IgnoreAllNonExisting();

            Mapper.CreateMap<CharacterSkill, VMCharacterSkill>()
                .ForMember(dest => dest.CharacterId, opt => opt.MapFrom(src => src.Character.Id))
                .IgnoreAllNonExisting();
            Mapper.CreateMap<CharacterSkill, VMCharacterSkill_GridItem>()
                .ForMember(dest => dest.CharacterId, opt => opt.MapFrom(src => src.Character.Id))
                .IgnoreAllNonExisting();
            Mapper.CreateMap<VMCharacterSkill, CharacterSkill>().IgnoreAllNonExisting();

            Mapper.CreateMap<CharacterSpecial, VMCharacterSpecial>().IgnoreAllNonExisting();
            Mapper.CreateMap<CharacterSpecial, VMCharacterSpecial_GridItem>().IgnoreAllNonExisting();
            Mapper.CreateMap<VMCharacterSpecial, CharacterSpecial>().IgnoreAllNonExisting();

            Mapper.CreateMap<PackageType, VMPackageType>().IgnoreAllNonExisting();
            Mapper.CreateMap<VMPackageType, PackageType>().IgnoreAllNonExisting();
        }

        private static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
        {
            var sourceType = typeof(TSource);
            var destinationType = typeof(TDestination);
            var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
            foreach (var property in existingMaps.GetUnmappedPropertyNames())
            {
                expression.ForMember(property, opt => opt.Ignore());
            }
            return expression;
        }

    }
}
